﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WF.DAL;
using WF.Common;
using WF.Model;
using System.Data.Linq.SqlClient;
using System.Data;

namespace WF.BusinessObject
{
    public class SecurityManager : BOBase
    {
        #region 构造函数

        public SecurityManager() : base() { }
        public SecurityManager(WFDBDataContext DataContext) : base(DataContext) { }
        #endregion

        public const string CommonUserRoleID = "00000000-00000000-0000-000000000000";
        public const string CommonUserRoleName = "普通用户";

        public const string AdminUserRoleID = "00000000-00000000-0000-000000000001";
        public const string AdminUserRoleName = "系统管理员";

        /// <summary>
        /// 判断用户是否有权限访问该url
        /// </summary>
        /// <param name="userId">访问用户</param>
        /// <param name="url">访问的url</param>
        /// <returns></returns>
        public bool IsAuthorized(string userId, string url)
        {
            if (url.EndsWith(".axd", StringComparison.CurrentCultureIgnoreCase))
            {
                return true;
            }

            if (this.DataContext.NonAuthFilterUrls.Where(o => SqlMethods.Like(url.ToUpper(), o.Url.ToUpper() + "%") && (o.FlagDeleted == 0)).Count() > 0)
            {
                return true;
            }

            if ((null == System.Web.HttpContext.Current) || (null == System.Web.HttpContext.Current.Session) || (null == System.Web.HttpContext.Current.Session[SessionKeys.CurrentUser]))
            {
                return false;
            }

            SessionManager sm = new SessionManager();

            if ((from a in this.DataContext.Roles
                 where a.RoleID == sm.CurrentUser.RoleID
                 from b in a.RoleAuthOperates
                 from c in b.Operate.OperatePages
                 where c.PageUrl.ToUpper().Equals(url.ToUpper())
                 select 1).Count() > 0)
            {
                return true;
            };

            return false;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="LoginName"></param>
        /// <returns></returns>
        public UserProfile GetUserProfile(string LoginName)
        {
            UserProfile userProfile = new UserProfile();
            List<RoleAssign> Roles = new List<RoleAssign>();
            List<PositionAssign> Positions = new List<PositionAssign>();

            //string emp = null;
            bool IsError = false;
            //域验证登陆成功后去业务数据库中查是否有这个用户，没有则去K3匹配，K3中匹配成功后把该用户写入库数据库；如果没有获取到则匹配预设用户，如果都匹配不成功则不能进入系统
            //gsl
            WF.DAL.Employee emp = null;
            var tEmp = this.DataContext.Employees.Where(o => ((o.DomainAccount.ToUpper() == LoginName.ToUpper()) || (o.DomainAccount.ToUpper() == @"CENTALINE\" + LoginName.ToUpper())) && (o.FlagDeleted == 0));
            if (tEmp.Count() > 1)
            {
                this.DataContext.Employees.DeleteAllOnSubmit(tEmp);
                this.DataContext.SubmitChanges();
            }
            else
                emp = tEmp.SingleOrDefault();

            if (null == emp)
            {
                //k3 验证登陆用户
                Com.Object.Fields fd = new Com.Object.Fields();
                SHZYK3.K3 probj = new SHZYK3.K3();
                DataSet ds = null;
                try
                {
                    ds = probj.GetEmpInfoByDomainAccount(LoginName);

                    fd.LoadDataFromDataSet(ds, true);
                    //string loginName = "CENTALINE\\" + fd.GetFieldValue("Email").ToString().Split('@')[0];
                    string loginName = fd.GetFieldValue("Email").ToString().Split('@')[0];
                    userProfile.LoginName = loginName; // fd.GetFieldValue("Email");
                    userProfile.Empname = fd.GetFieldValue("EmpName");
                    userProfile.DeptID = fd.GetFieldValue("DeptID");
                    userProfile.EmpID = fd.GetFieldValue("EmpID");
                    userProfile.DeptName = fd.GetFieldValue("DeptName");
                    userProfile.DeptPath = fd.GetFieldValue("DeptCode");
                    //userprofile.
                }
                catch
                {
                    IsError = true;
                }
                //AD验证登陆用户
                if (null == ds || IsError == true)
                {
                    try
                    {
                        AD.AD ad = new AD.AD();
                        ds = ad.ListADUserProperties("", LoginName);
                        fd.LoadDataFromDataSet(ds, true);
                        userProfile.LoginName = LoginName;  //must
                        userProfile.Empname = fd.GetFieldValue("cn");    //must
                        userProfile.EmpID = Guid.NewGuid().ToString();
                        userProfile.DeptID = "09927b3e-c3b6-4075-a739-93ff555ca0c0";
                        //userProfile.EmpID = "1f956egc-a476-4853-b382-7840eb4165f6";
                        IsError = false;
                    }
                    catch
                    {
                        IsError = true;
                    }

                }
                //预设的管理员账号
                if (null == ds || IsError == true)
                {
                    if (IsPresetAdmin(LoginName))
                    {
                        /*
                        Department departBO = new Department(DataContext);
                        DepartmentEntity rootDept = departBO.GetRootDepartment();

                        userProfile.DeptID = rootDept.ID;
                        userProfile.DeptName = rootDept.Name;
                        userProfile.DeptPath = rootDept.Path;*/
                        userProfile.DeptID = "00000000-00000000-0000-000000000000";
                        userProfile.DeptName = "";
                        userProfile.DeptPath = "";

                        //userProfile.EmpID = "00000000-00000000-0000-000000000000";
                        userProfile.EmpID = Guid.NewGuid().ToString();
                        userProfile.Empname = LoginName;
                        userProfile.EmpNo = "00000000";
                        userProfile.HaveMutilRole = false;
                        userProfile.LoginName = LoginName;
                        userProfile.RoleID = SecurityManager.AdminUserRoleID;
                        userProfile.RoleName = SecurityManager.AdminUserRoleName;
                        userProfile.PositionName = "";
                        userProfile.PositionID = "";
                        userProfile.HaveMutilPosition = false;
                        userProfile.HaveMutilRole = false;
                        userProfile.Roles = Roles;
                        userProfile.Positions = Positions;
                    }
                    else
                    {
                        throw new BusinessException(string.Format("没有账号{0}的员工信息", LoginName));
                    }
                }
                //加入职员表
                EmployeeEntity empEntity = new EmployeeEntity();
                empEntity.ID = userProfile.EmpID;
                empEntity.Name = userProfile.Empname;
                string domainAccount = "";
                if (fd.GetFieldValue("DomainAccount") == "")
                    domainAccount = fd.GetFieldValue("sAMAccountName");
                else
                    domainAccount = fd.GetFieldValue("DomainAccount");
                empEntity.DomainAccount = domainAccount;
                empEntity.EmpNo = fd.GetFieldValue("EmpCode");
                empEntity.DeptID = userProfile.DeptID;
                empEntity.FlagDeleted = 0;
                empEntity.ModDate = System.DateTime.Now;
                empEntity.SyncTime = System.DateTime.Now;
                Employee empBO = new Employee();
                empBO.Add(empEntity);
            }

            else
            {
                #region
                /*
                List<DAL.EmployeeToRole> EmployeeToRoles = emp.EmployeeToRoles.ToList();
                List<DAL.EmployeePositionRole> EmployeePositionRoles = emp.EmployeePositionRoles.ToList();

                Department deptBO = new Department();
                foreach (DAL.EmployeeToRole item in EmployeeToRoles)
                {
                    RoleAssign role = new RoleAssign();
                    role.RoleId = item.RoleID;
                    role.RoleName = item.Role1.RoleName;
                    role.DepartmentID = item.DepartmentID;
                    role.DepartmentName = item.Department.DeptName;
                    role.DeptPath = item.Department.Path;
                    role.PositionID = "";
                    role.PositionName = "";

                    foreach (DAL.RoleAuthOperate op in item.Role1.RoleAuthOperates)
                    {
                        AuthOperate obj = new AuthOperate();
                        obj.DeptRange = op.DeptRange.Value;
                        obj.OperateID = op.OperateID;
                        obj.OperateName = op.Operate.OperateName;
                        obj.OperateNo = op.Operate.OperateNo;
                        role.AuthOperates[obj.OperateNo] = obj;
                        
                    }
                    Roles.Add(role);
                }

                预设的管理员账号
                if (IsPresetAdmin(LoginName))
                {
                    Department departBO = new Department(DataContext);
                    DepartmentEntity rootDept = departBO.GetRootDepartment();

                    userProfile.DeptID = rootDept.DeptNo;
                    userProfile.DeptName = rootDept.Name;
                    userProfile.DeptPath = rootDept.Path;

                    RoleAssign role = new RoleAssign();
                    role.RoleId = SecurityManager.AdminUserRoleID;
                    role.RoleName = SecurityManager.AdminUserRoleName;
                    role.DepartmentID = rootDept.ID;
                    role.DepartmentName = rootDept.Name;
                    role.DeptPath = rootDept.Path;
                    role.PositionID = "";
                    role.PositionName = "";

                    Roles.Add(role);
                }

                
                foreach (DAL.EmployeePositionRole item in EmployeePositionRoles)
                {
                    if ((null != item.Position))
                    {
                        RoleAssign role = new RoleAssign();
                        PositionAssign position = new PositionAssign();

                        if (null == item.Position.Role1)
                        {
                            role.RoleId = SecurityManager.CommonUserRoleID;
                            role.RoleName = SecurityManager.CommonUserRoleName;
                        }
                        else
                        {
                            role.RoleId = item.Position.RoleID;
                            role.RoleName = item.Position.Role1.RoleName;
                            foreach (DAL.RoleAuthOperate op in item.Position.Role1.RoleAuthOperates)
                            {
                                AuthOperate obj = new AuthOperate();
                                if (op.DeptRange.HasValue)
                                {
                                    obj.DeptRange = op.DeptRange.Value;
                                }
                                else
                                {
                                    obj.DeptRange = (short)Common.AuthDeptRange.无;
                                }

                                obj.OperateID = op.OperateID;
                                obj.OperateNo = op.Operate.OperateNo;
                                obj.OperateName = op.Operate.OperateName;
                                role.AuthOperates[obj.OperateNo] = obj;
                            }
                        }
                        role.DepartmentID = item.Position.Department.DeptID;
                        role.DepartmentName = item.Position.Department.DeptName;
                        role.DeptPath = item.Position.Department.Path;
                        role.PositionID = item.Position.PositionID;
                        role.PositionName = item.Position.PositionName;

                        position.DepartmentID = item.Position.Department.DeptID;
                        position.DepartmentName = item.Position.Department.DeptName;
                        position.PositionID = item.Position.PositionID;
                        position.PositionName = item.Position.PositionName;

                        Roles.Add(role);
                        Positions.Add(position);
                    }
                }
                */
                #endregion

                userProfile.EmpID = emp.EmpID;
                userProfile.Empname = emp.EmpName;
                userProfile.EmpNo = emp.EmpNo;
                userProfile.LoginName = LoginName;
                //userProfile.DeptID = emp.DeptID;
                //用k3 信息更新用户部门信息
                Com.Object.Fields fd = new Com.Object.Fields();
                SHZYK3.K3 probj = new SHZYK3.K3();
                DataSet ds = null;
                try
                {
                    ds = probj.GetEmpInfoByDomainAccount(LoginName);

                    fd.LoadDataFromDataSet(ds, true);
                    userProfile.DeptID = fd.GetFieldValue("DeptID");
                    userProfile.DeptName = fd.GetFieldValue("DeptName");
                    userProfile.DeptPath = fd.GetFieldValue("DeptCode");
                }
                catch
                {
                }

                #region
                //if (Roles.Count == 1)
                //{
                //    userProfile.DeptID = Roles[0].DepartmentID;
                //    userProfile.DeptName = Roles[0].DepartmentName;
                //    userProfile.DeptPath = Roles[0].DeptPath;
                //    userProfile.HaveMutilRole = false;
                //    userProfile.RoleID = Roles[0].RoleId;
                //    userProfile.RoleName = Roles[0].RoleName;

                //}
                //else if (Roles.Count > 1)
                //{
                //    userProfile.HaveMutilRole = true;
                //}

                //if (Positions.Count == 1)
                //{
                //    userProfile.PositionID = Positions[0].PositionID;
                //    userProfile.PositionName = Positions[0].PositionName;

                //}
                //else if (Positions.Count > 1)
                //{
                //    userProfile.HaveMutilPosition = true;
                //}

                //userProfile.Roles = Roles;
                //userProfile.Positions = Positions;
                #endregion
            }
            return userProfile;
        }

        /// <summary>
        /// 获取部门
        /// </summary>
        /// <returns></returns>
        public List<vDeptTree> GetAllUnit(string[] deptName = null)
        {

            var allUnit = from a in new BOBaseKQ().DataContext.HRContainer
                          select new vDeptTree
                          {
                              dCount = a.Path.Length - a.Path.Replace(".", "").Length,
                              RowGuid = a.RowGUID,
                              Name = a.name,
                              Path = a.Path,
                              DeptNo = a.DeptNo
                          };
            if (deptName != null)
                allUnit = allUnit.Where(a => deptName.Contains(a.Name));
            return allUnit.OrderBy(m => m.dCount).ToList();
        }

        /// <summary>
        /// 获取排除人员信息
        /// </summary>
        /// <param name="users"></param>
        /// <returns></returns>
        public List<vUserLimit> GetLimiteUsers(string[] users)
        {
            if (users != null)
            {
                var data = from a in this.DataContext.Employees
                           where users.Contains(a.EmpNo) || users.Contains(a.EmpName) || users.Contains(a.DomainAccount)
                           select new vUserLimit
                           {
                               Name = a.EmpName,
                               Code = a.EmpNo,
                               DomainName = a.DomainAccount,
                               Status="已开通"
                           };
                return data.ToList();
            }
            return null;
        }
        /// <summary>
        /// 获取当前用户的Html菜单
        /// </summary>
        /// <returns></returns>
        public string GetCurrentUserHtmlMenu()
        {
            SessionManager sm = new SessionManager();
            MenuItem menu = new MenuItem(DataContext);

            UserProfile currentUser = sm.CurrentUser;
            bool _hasDisplayMenuItem;
            return GetHtmlMenu(currentUser.RoleID, null, out _hasDisplayMenuItem);
        }

        public string GetHtmlMenu(string RoleID, MenuItemEntity menuItemEntity, out bool hasDisplayMenuItem)
        {
            bool isRoot = (menuItemEntity == null);
            bool isLi;

            hasDisplayMenuItem = false; ;

            StringBuilder sb = new StringBuilder();
            string subHtmlMenu = string.Empty;

            if (null == menuItemEntity)
            {
                isLi = false;
            }
            else
            {
                isLi = (null != menuItemEntity.DBEntity.ParentItem);
            }

            MenuItem menuBo = new MenuItem(DataContext);
            List<MenuItemEntity> subMenus = menuBo.GetSubMenuItems(menuItemEntity);

            foreach (MenuItemEntity menuItem in subMenus)
            {
                if (IsMenuItemAuth(RoleID, menuItem))
                {
                    hasDisplayMenuItem = true;
                    List<MenuItemEntity> subSubMenus = menuBo.GetSubMenuItems(menuItem);

                    subHtmlMenu = GetHtmlMenu(RoleID, menuItem, out hasDisplayMenuItem);
                    if (hasDisplayMenuItem)
                    {
                        if (isRoot)
                            sb.Append(string.Format("<dl><dt class=\"title_close\">{0}</dt>", menuItem.MenuName));
                        else
                        {
                            if ((subSubMenus.Count == 0) && (!isLi))
                                sb.Append(string.Format("<dd class=\"noselect\" id=\"{0}\" onclick=\"ShowPage('{0}','{1}');\">{0}</dd>", menuItem.MenuName, menuItem.MenuURL));
                            else if ((subSubMenus.Count == 0) && (isLi))
                                sb.Append(string.Format("<li class=\"li_list\" id=\"{0}\" onclick=\"ShowPage('{0}','{1}');\">{0}</li>", menuItem.MenuName, menuItem.MenuURL));
                            else
                                sb.Append(string.Format("<dd class=\"dd_more\"><div><ul><li class=\"li_title_close\">{0}</li>", menuItem.MenuName));
                        }

                        sb.Append(subHtmlMenu);

                        if (isRoot)
                            sb.Append("</dl>");
                        else
                        {
                            if (subSubMenus.Count > 0)
                                sb.Append("</div></dd>");
                        }
                    }
                }
            }

            if (subMenus.Count == 0)
            {
                hasDisplayMenuItem = true;
            }
            return sb.ToString();
        }

        /// <summary>
        /// 获取指定角色的Html菜单
        /// </summary>
        /// <param name="RoleID"></param>
        /// <param name="menuItemEntity"></param>
        /// <param name="sb"></param>
        public void GetHtmlMenu(string RoleID, MenuItemEntity menuItemEntity, StringBuilder sb)
        {
            bool isRoot = (menuItemEntity == null);
            bool isLi;
            if (null == menuItemEntity)
            {
                isLi = false;
            }
            else
            {
                isLi = (null != menuItemEntity.DBEntity.ParentItem);
            }

            MenuItem menuBo = new MenuItem(DataContext);
            List<MenuItemEntity> menus = menuBo.GetSubMenuItems(menuItemEntity);
            foreach (MenuItemEntity menuItem in menus)
            {
                if (IsMenuItemAuth(RoleID, menuItem))
                {
                    List<MenuItemEntity> subMenus = menuBo.GetSubMenuItems(menuItem);
                    if (isRoot)
                        sb.Append(string.Format("<dl><dt class=\"title_close\">{0}</dt>", menuItem.MenuName));
                    else
                    {
                        if ((subMenus.Count == 0) && (!isLi))
                            sb.Append(string.Format("<dd class=\"noselect\" id=\"{0}\" onclick=\"ShowPage('{0}','{1}');\">{0}</dd>", menuItem.MenuName, menuItem.MenuURL));
                        else if ((subMenus.Count == 0) && (isLi))
                            sb.Append(string.Format("<li class=\"li_list\" id=\"{0}\" onclick=\"ShowPage('{0}','{1}');\">{0}</li>", menuItem.MenuName, menuItem.MenuURL));
                        else
                            sb.Append(string.Format("<dd class=\"dd_more\"><div><ul><li class=\"li_title_close\">{0}</li>", menuItem.MenuName));
                    }

                    if (subMenus.Count > 0)
                    {

                        GetHtmlMenu(RoleID, menuItem, sb);
                    }

                    if (isRoot)
                        sb.Append("</dl>");
                    else
                    {
                        if (subMenus.Count > 0)
                            sb.Append("</div></dd>");
                    }
                }
            }
        }

        /// <summary>
        /// 角色对菜单是否有操作权限
        /// </summary>
        /// <param name="RoleID"></param>
        /// <param name="menuItemEntity"></param>
        /// <returns></returns>
        public bool IsMenuItemAuth(string RoleID, MenuItemEntity menuItemEntity)
        {
            if ((string.IsNullOrEmpty(menuItemEntity.OperateID)) || (menuItemEntity.DBEntity.Operate.RoleAuthOperates.Where(o => o.RoleID == RoleID).Count() > 0))
            {
                return true;
            }
            else
            {
                return false;
            };
        }

        /// <summary>
        /// 指定的登陆用户是否预置的管理员


        /// </summary>
        /// <param name="LoginName"></param>
        /// <returns></returns>
        public bool IsPresetAdmin(string LoginName)
        {
            return true;
            //if (null != System.Configuration.ConfigurationManager.AppSettings[AppSettingKeys.SuperUsers])
            //{
            //    string users = (string)System.Configuration.ConfigurationManager.AppSettings[AppSettingKeys.SuperUsers];
            //    List<string> superusers = new List<string>(users.Split(','));
            //    return superusers.Exists(o=>o.ToUpper() == LoginName.ToUpper());
            //}
            //else
            //{
            //    return false;
            //}           
        }

        /// <summary>
        /// 检查当前用户对一个操作的权限
        /// </summary>
        /// <param name="OperateNo"></param>
        /// <returns></returns>
        public AuthDeptRange IsOperateAuthoried(string OperateNo)
        {
            SessionManager sm = new SessionManager(DataContext);
            Operate operateBO = new Operate(DataContext);
            OperateEntity Operate = operateBO.GetByOperateNo(OperateNo);
            if (null == Operate)
            {
                return AuthDeptRange.无;
            }
            if (null != sm.CurrentUser)
            {
                if (IsPresetAdmin(sm.CurrentUser.LoginName))
                {
                    return AuthDeptRange.所有;
                }

                RoleAssign currentRole = sm.CurrentUser.Roles.FirstOrDefault(o => o.RoleId == sm.CurrentUser.RoleID);

                if ((null != currentRole) && (currentRole.AuthOperates.Keys.Contains(OperateNo)))
                {
                    if (Operate.DeptRelate > 0)
                    {
                        return (AuthDeptRange)currentRole.AuthOperates[OperateNo].DeptRange;
                    }
                    else
                    {
                        return AuthDeptRange.所有;
                    }
                }
                else
                {
                    return AuthDeptRange.无;
                }
            }
            else
            {
                return AuthDeptRange.无;
            }

        }

        /// <summary>
        /// 检查当前用户对一个操作的权限
        /// </summary>
        /// <param name="OperateName"></param>
        /// <param name="DeptID"></param>
        /// <returns></returns>
        public AuthDeptRange IsOperateAuthoried(string OperateName, string DeptID, string EmpID)
        {
            SessionManager sm = new SessionManager(DataContext);
            AuthDeptRange authDeptRange = IsOperateAuthoried(OperateName);
            if (IsPresetAdmin(sm.CurrentUser.LoginName))
            {
                return AuthDeptRange.所有;
            }
            if ((authDeptRange == AuthDeptRange.无) || (authDeptRange == AuthDeptRange.所有))
            {
                return authDeptRange;
            }
            else if (authDeptRange == AuthDeptRange.本人)
            {
                if (string.IsNullOrEmpty(EmpID))
                {
                    return authDeptRange;
                }
                if (sm.CurrentUser.EmpID == EmpID)
                {
                    return authDeptRange;
                }
                else
                {
                    return AuthDeptRange.无;
                }
            }
            else if (authDeptRange == AuthDeptRange.本部门)
            {
                return AuthDeptRange.本部门;
                /*bak
                if (string.IsNullOrEmpty(DeptID))
                {
                    return AuthDeptRange.本部门;
                }
                string currentDeptID = sm.CurrentUser.DeptID;
                Department deptBO = new Department(DataContext);

                DepartmentEntity currentDept = deptBO.GetById(currentDeptID);
                DepartmentEntity targetDept = deptBO.GetById(DeptID);

                if ((null != targetDept.Path) && (null != currentDept.Path) && (targetDept.Path.StartsWith(currentDept.Path)))
                {
                    return AuthDeptRange.本部门;
                }
                else
                {
                    return AuthDeptRange.无;
                }*/
            }
            else
            {
                return AuthDeptRange.无;
            }
        }
    }
}
